package simulation;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import view.View;

/**
 * @author  Owner
 */
public class Painter implements PaintListener {

	/**
	 * @uml.property  name="dynamicSim"
	 * @uml.associationEnd  multiplicity="(0 -1)"
	 */
	private IntSimulator[] dynamicSim;

	private int[] targets;

	private int canvasHeight;

	private boolean paused;
	
	private Image image = new Image(null, getClass().getResourceAsStream("pauseoncan.png"));
	
	private Color barColor = new Color(null,new RGB(63,98,178));
	
	private int canvasWidth;
	
	private static Painter inst;

	public static Painter getInstance() {
		if (inst == null)
			inst = new Painter();
		return inst;
	}

	public void paintControl(PaintEvent e) {
		// calculating positions and .:.
		if (this.dynamicSim != null) {
			/**
			 * TODO:
			 */
			synchronized (dynamicSim) {

				int t = dynamicSim.length;
				for (int i = 0; i < t; i++) {
					/**
					 * TODO:
					 */
					try {
						
						int roundedWidth = (int) (dynamicSim[i].width * ((float) 96 / (float) 100));
						int suffexWidth = roundedWidth - 1;
						int suffexX = (int) (dynamicSim[i].x + (dynamicSim[i].width * ((float) 10 / (float) 100)));
						int suffexY = dynamicSim[i].y
								- (suffexX - dynamicSim[i].x - 1);
						int suffexHeight = canvasHeight - suffexY;
						
						/**
						 * TODO:
						 */
						/******************************modification**************************/
						//synchronized (View.getInstance().getDisplay()) {						
						e.gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY));
						e.gc.fillRoundRectangle(suffexX, suffexY, suffexWidth,suffexHeight, 15, 15);
						// e.gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE));
						e.gc.setBackground(barColor);
						e.gc.fillRoundRectangle(dynamicSim[i].x,dynamicSim[i].y, roundedWidth,dynamicSim[i].height, 15, 15);
						//}
						/*****************************************************************/
					} catch (NullPointerException exception) {

					}
				}
			}
		}
		if (paused)
			e.gc.drawImage(image, canvasWidth / 2 -50, canvasHeight / 2);
	}
	
	public void setWorkArray(Integer[] workArray) {
		this.canvasWidth=View.getInstance().getCanvasWidth();
		this.canvasHeight=View.getInstance().getCanvasHeight();
		this.dynamicSim = new IntSimulator[workArray.length];
		this.targets = new int[workArray.length];
		float ratio = 1;
		
		int min = 999999999;
		final int EPSLON = 20;
		for (int i = 0; i < workArray.length; i++) {
			if (workArray[i] < min) {
				min = workArray[i];
			}
			dynamicSim[i] = new IntSimulator();
			dynamicSim[i].width = (int) ((float)canvasWidth / (float) workArray.length);
			dynamicSim[i].x = i * dynamicSim[i].width;
			dynamicSim[i].height = workArray[i];
			targets[i] = dynamicSim[i].x;
		}
		
		if(min <= 0){
			for(int i = 0; i < dynamicSim.length; i++){
				dynamicSim[i].height=dynamicSim[i].height-min;
				dynamicSim[i].height+=EPSLON;
			}
		}
		
		int max = -999999999;
		for (int i = 0; i < dynamicSim.length; i++) {
			if (dynamicSim[i].height > max) {
				max = dynamicSim[i].height;
			}
		}
		if(max > canvasHeight || max < canvasHeight){
			ratio = (float)canvasHeight / (float)max;
			for (int i = 0; i < dynamicSim.length; i++) {
				dynamicSim[i].height *= ratio;
				dynamicSim[i].y = canvasHeight - dynamicSim[i].height;
			}
		}
		if (!View.getInstance().getCanvas().isDisposed()) {
			View.getInstance().getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (!View.getInstance().getCanvas().isDisposed())
						View.getInstance().getCanvas().redraw();
				}
			});
		}
	}

	public IntSimulator[] getDynamicSimulators() {
		return dynamicSim;
	}

	/**
	 * @return  the targets
	 * @uml.property  name="targets"
	 */
	public int[] getTargets() {
		return targets;
	}
	
	public void setMergeArray(Integer[] workArray){
	    this.canvasWidth=View.getInstance().getCanvasWidth();
		this.canvasHeight=View.getInstance().getCanvasHeight();
		this.targets = new int[workArray.length];
		float ratio = 1;
		
		int min = 999999999;
		final int EPSLON = 20;
		for (int i = 0; i < workArray.length; i++) {
			if (workArray[i] < min) {
				min = workArray[i];
			}
			dynamicSim[i].width = (int) ((float)canvasWidth / (float) workArray.length);
			dynamicSim[i].x = i * dynamicSim[i].width;
			dynamicSim[i].height = workArray[i];
			targets[i] = dynamicSim[i].x;
		}
		
		if(min <= 0){
			for(int i = 0; i < dynamicSim.length; i++){
				dynamicSim[i].height=dynamicSim[i].height-min;
				dynamicSim[i].height+=EPSLON;
			}
		}
		
		int max = -999999999;
		for (int i = 0; i < dynamicSim.length; i++) {
			if (dynamicSim[i].height > max) {
				max = dynamicSim[i].height;
			}
		}
		if(max > canvasHeight || max < canvasHeight){
			ratio = (float)canvasHeight / (float)max;
			for (int i = 0; i < dynamicSim.length; i++) {
				dynamicSim[i].height *= ratio;
				dynamicSim[i].y = canvasHeight - dynamicSim[i].height;
			}
		}
		if(!View.getInstance().getCanvas().isDisposed()){
			View.getInstance().getDisplay().asyncExec(new Runnable(){
			    public void run() {
				View.getInstance().getCanvas().redraw();
			    }
			});
		}
	}
	
	/**
	 * @param paused  the paused to set
	 * @uml.property  name="paused"
	 */
	public void setPaused(boolean paused) {
		this.paused = paused;
	}
}
